using System;
using Microsoft.Practices.ObjectBuilder2;

namespace Common.Unity.Extensions.PropertyMapper
{
	public struct PropertyMappingKey : IBuildKey
	{
		readonly Type source;
		readonly NamedTypeBuildKey targetBuildKey;

		public PropertyMappingKey( Type source, NamedTypeBuildKey targetBuildKey )
		{
			Guard.ArgumentNotNull( source, "source" );
			Guard.ArgumentNotNull( targetBuildKey, "targetBuildKey" );
			this.source = source;
			this.targetBuildKey = targetBuildKey;
		}

		public Type Source
		{
			get { return source; }
		}

		public NamedTypeBuildKey TargetBuildKey
		{
			get { return targetBuildKey; }
		}

		object IBuildKey.ReplaceType( Type newType )
		{
			return TargetBuildKey.ReplaceType( newType );
		}

		Type IBuildKey.Type
		{
			get { return TargetBuildKey.Type; }
		}

		public override int GetHashCode()
		{
			return source.GetHashCode() ^ targetBuildKey.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			if ( obj is PropertyMappingKey )
			{
				PropertyMappingKey key = (PropertyMappingKey)obj;
				return ( key.Source == Source && key.TargetBuildKey == TargetBuildKey );
			}
			return base.Equals(obj);
		}

		public static bool operator == ( PropertyMappingKey left, PropertyMappingKey right )
		{
			return left.Equals( right );
		}

		public static bool operator != ( PropertyMappingKey left, PropertyMappingKey right )
		{
			return !left.Equals( right );
		}

		public bool IsAssignableFrom( PropertyMappingKey other )
		{
			bool result = Source.IsAssignableFrom( other.Source ) && TargetBuildKey.Type.IsAssignableFrom( other.TargetBuildKey.Type ) && string.Compare( TargetBuildKey.Name, other.TargetBuildKey.Name ) == 0;
			return result;
		}
	}
}